package com.cm.tianwt.socks.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.cm.tianwt.socks.utils.Configs;
import com.cm.tianwt.socks.utils.LogUtils;

public class SocksHandlerManager {
	
	private static ExecutorService sExecutor;
	
	public static SocksHandler create(Socket clientSocket) {
		
		SocksHandler socksHandler = null;
		OutputStream outputStream = null;
		InputStream inputStream = null;
		int version = 0;
		
		try {
			inputStream = clientSocket.getInputStream();
			outputStream = clientSocket.getOutputStream();
			
			version = getVersion(inputStream);
			
			
			LogUtils.D("SocksHandlerManager",getVersionName(version)+"," + clientSocket.getInetAddress().getHostName() +":" + clientSocket.getPort());
			
			switch (version) {
				case Configs.VERSION_SOCKS_V5:
					socksHandler = new SocksV5Impl(clientSocket,inputStream,outputStream);
					break;
					
				case Configs.VERSION_SOCKS_V4:
					socksHandler = new SocksV4Impl(clientSocket,inputStream,outputStream);
					break;

				default:
					LogUtils.E("Don't Support Socks VERSION: " +version);
					break;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			if(socksHandler!=null) {
				socksHandler.shutDown();
			}
			return null;
		}
		return socksHandler;
		
	}


	
	private static String getVersionName(int version) {
		String name = "Unkown Socks version";
		switch (version) {
		case Configs.VERSION_SOCKS_V4:
			name = "SocksV4";
			break;

		case Configs.VERSION_SOCKS_V5:
			name = "SocksV5";
			break;

		default:
			break;
		}
		return name;
	}



	private static int getVersion(InputStream inputStream) throws IOException {
		int version = inputStream.read();
		return  version;
	}

	public static synchronized void execute(SocksHandler socksHandler) {
		if(sExecutor==null) {
			sExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2+1);
		}
		sExecutor.execute(socksHandler);
		
	}

}
